import { formatHex, toBytes } from '../../electron-kit-extension/tool.js';
import HidManager from "../../electron-kit-hid/index.js";
import { chManager } from './defaultconfig.js';
export const SendType = Object.freeze({
    EQ: [0xAA],//
    EQ_UNIT: [0xAB],
    PHASE: [0xBB],
    DELAY: [0xCC],
    DB: [0xDB],
    DB_ALL: [0xEE],
    PASS_HIGH: [0xDD],
    PASS_LOW: [0xDE],
    BYPASS: [0xFF, 0x00],
    RESTORE: [0xFF, 0x01],
    RESET_EQ: [0xFF, 0x02],
    RESET_DSP: [0xAA, 0xFF, 0xFF],
    SUM_2CH: [0xAA, 0x83, 0xF2],
    SUM_4CH: [0xAA, 0x83, 0xF4],
    SUM_6CH: [0xAA, 0x83, 0xF6],
    SUM_SUM: [0xAA, 0x83, 0xFA],
    SUM_CUSTOM: [0xAA, 0x83, 0xF0],
    SUM_USB_BT: [0xAA, 0x83, 0xFB],  //BT | USB | AUX的合频
    SUM_OPTICAL: [0xAA, 0x83, 0xFC], //光纤 ｜ 同轴的合频
    NOISE: [0xCC, 0xCC],
    LIMIT: [0xFA],
    SOURCE: [0xAA, 0x82],
    LOAD_DEVICE: [0x47, 0x45, 0x54, 0x44, 0x53, 0x50, 0x54, 0x59, 0x55, 0x55],
    UPDATE: [],///直接发送
    SAVE_TO_MCU: [0xFF, 0xCC],//保存到设备
    GET_DATA_MCU: [0x46, 0x13],//调用设备的数据
});
export let HID;
export function setHid({ vendorId = 0xA8A4, productId = 0x2255, interfaceId = 0 } = {}) {
    HID = new HidManager({ vendorId: vendorId, productId: productId, interfaceId: interfaceId });
}

export function sendHiD(type, { ch = null, sign = null, data = null, pass = null } = {}) {
    const bytes = toBytesList(type, { ch: ch, sign: sign, data: data, pass: pass });
    if (ch != null && ch.num < 1 && type !== SendType.UPDATE) return;
    HID.sendHidData(bytes);
}

export function toBytesList(type, { ch = null, sign = null, data = null, pass = null } = {}) {
    const base = type;
    let bytes = [];
    switch (type) {
        case SendType.EQ:
        case SendType.EQ_UNIT: {
            if (sign === null) return;
            const num = 0xC0 + ch.num;
            const index = sign.index;
            const freq = toBytes(parseInt(sign.freq), 2);
            const q = toBytes(parseFloat(sign.q) * 100, 2)
            const gain = toBytes((parseInt(sign.gain, 10) + sign.max_gain) * 10, 2);
            bytes = base.concat(num, index, freq, q, gain);
            break;
        }
        case SendType.PHASE: {
            const num = 0xC0 + ch.num;
            const phase = ch.phase ? 0 : 1;
            bytes = base.concat(num, phase);
            break;
        }
        case SendType.DELAY: {
            const delay = toBytes(ch.delay * 100, 2);
            bytes = base.concat(0xC0 + ch.num, delay);
            break;
        }
        case SendType.DB: {
            const num = 0xC0 + ch.num;
            const mute = ch.mute ? 1 : 0;
            const db = toBytes(Math.abs(parseInt(ch.db, 10)) * 10, 2);
            const phase = ch.phase ? 0 : 1;
            bytes = base.concat(num, mute, db, phase);
            break;
        }
        case SendType.DB_ALL: {
            const mute = chManager.mute ? 1 : 0;
            const db = toBytes(Math.abs(parseInt(chManager.db, 10)) * 10, 2);
            bytes = base.concat(mute, db);
            break;
        }
        case SendType.PASS_HIGH:
        case SendType.PASS_LOW: {
            if (ch.num < 1 || pass === null) return;
            const num = 0xC0 + ch.num;
            const passtype = pass.types[pass.type_index];
            const freq = toBytes(pass.freq, 2);
            bytes = base.concat(num, passtype.type, passtype.slope_hex, freq);
            break;
        }
        case SendType.BYPASS:
        case SendType.RESTORE: {
            bytes = base;
            break;
        }
        case SendType.RESET_EQ: {
            const num = ch != null && ch.num > 0 ? ch.num : 0;
            bytes = base.concat(0xC0 + num);
            break;
        }
        case SendType.RESET_DSP: {

            break;
        }
        case SendType.SUM_2CH:
        case SendType.SUM_4CH:
        case SendType.SUM_6CH:
        case SendType.SUM_SUM: {
            bytes = base;
            break;
        }
        case SendType.SUM_CUSTOM: {
            let targetlist = ch.target_list.map((num) => num === 0 ? 0 : 1);
            //因为板子的这个命令，限制了14个字节，如果12通道加上指令就16个字节了。这里改成8个通道 对应8bit的方式。取消下面直接使用targetlist
            if (chManager.chlist.length < 10) {
                bytes = base.concat(0xC0 + ch.num, targetlist);
            } else {
                const page = Math.ceil(targetlist.length / 8);
                targetlist = targetlist.concat(Array(page * 8 - targetlist.length).fill(0));
                console.log('=========== targetlist :', targetlist.map(($0) => `${$0}`).join(' |'));
                const result = [];
                for (let i = 0; i < page; i++) {
                    const arr = targetlist.slice(i * 8, (i + 1) * 8).reverse();
                    const bit_num = arr.reduce((acc, bit) => (acc << 1) | bit, 0);
                    console.log('=========== bit :', bit_num, formatHex([bit_num]), arr.map(($0) => `${$0}`).join(' |'));
                    result.push(bit_num);
                }
                bytes = base.concat(0xC0 + ch.num, result);
            }
            break;
        }

        case SendType.SUM_USB_BT:
        case SendType.SUM_OPTICAL: {
            const targetlist = ch.target_list.map((num) => num === 0 ? 0 : 1);
            bytes = base.concat(0xC0 + ch.num, targetlist);
            break;
        }
        case SendType.NOISE: {
            bytes = base.concat(chManager.noise);
            break;
        }
        case SendType.LIMIT: {
            const num = 0xC0 + ch.num;
            bytes = base.concat(num, parseInt(ch.limit_level, 10) + 24, parseInt(ch.limit_speed, 10), toBytes(parseInt(ch.limit_release, 10), 2));
            break;
        }
        case SendType.SOURCE: {
            if (data === null) return;
            bytes = base.concat(data);
            break;
        }
        case SendType.LOAD_DEVICE: {
            if (data === null) {
                bytes = base;
            } else {
                const num = parseInt(data.num);
                const index = parseInt(data.index);
                bytes = base.concat(num, index);
            }
            break;
        }
        case SendType.UPDATE: {
            if (data === null) return;
            bytes = base.concat(data);
        }
        case SendType.SAVE_TO_MCU: {
            if (data === null) return;
            bytes = base.concat(data);
        }
        case SendType.GET_DATA_MCU: {
            if (data === null) return;
            bytes = base.concat(data);
        }
        default: {
            break;
        }
    }
    return bytes;

}